home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_02 / dosutil / cmos.c < prev    next >
C/C++ Source or Header  |  1994-03-20  |  4KB  |  150 lines

  1. /*
  2.  * Program to save/restore/verify the CMOS data of an AT BIOS.
  3.  *
  4.  * Copyright 1991-1994 Dave Dunfield
  5.  * All rights reserved.
  6.  *
  7.  * Compile with: cc cmos -fop
  8.  */
  9. #include <stdio.h>
  10.  
  11. #define MAX_SIZE 128-0x10    /* Maximum potential size of CMOS ram */
  12.  
  13. unsigned char buffer1[MAX_SIZE], buffer2[MAX_SIZE], verbose = -1;
  14.  
  15. int size = 32, ignore[50]; icount = 0;
  16.  
  17. char *help[] = {
  18.     "\nUse: CMOS <command> <filename> [options]\n",
  19.     "command: Save    - Save CMOS data to a file",
  20.     "         Restore - Recover CMOS data from file",
  21.     "         Verify  - Compare CMOS data to file\n",
  22.     "options: -Q      - QUIET, inhibit messages",
  23.     "         I=value - Ignore byte at this offset (Verify)",
  24.     "         S=value - Bytes of CMOS to SAVE  (default 32)\n",
  25.     "Copyright 1991 Dave Dunfield",
  26.     "All rights reserved",
  27.     0 };
  28.  
  29. /*
  30.  * Main program
  31.  */
  32. main(argc, argv)
  33.     int argc;
  34.     char *argv[];
  35. {
  36.     int i;
  37.     char *ptr;
  38.     FILE *fp;
  39.  
  40.     if(argc < 3) {
  41.         for(i = 0; help[i]; ++i) {
  42.             fputs(help[i], stderr);
  43.             putc('\n', stderr); }
  44.         return; }
  45.  
  46.     for(i=3; i < argc; ++i) {
  47.         ptr = argv[i];
  48.         switch((*ptr++ << 8) | *ptr++) {
  49.                 case '-q' :        /* Request QUIET mode */
  50.                 case '-Q' :
  51.                     verbose = 0;
  52.                     break;
  53.                 case 's=' :        /* Specify size to save */
  54.                 case 'S=' :
  55.                     size = atoi(ptr);
  56.                     break;
  57.                 case 'i=' :        /* Specify IGNORE bytes */
  58.                 case 'I=' :
  59.                     ignore[icount++] = atoi(ptr);
  60.                     break;
  61.                 default:
  62.                     fputs("Invalid option: ", stderr);
  63.                     fputs(argv[i], stderr);
  64.                     return; } }
  65.  
  66.     switch(*argv[1]) {
  67.         case 's' :        /* Save CMOS data to a file */
  68.         case 'S' :
  69.             read_cmos(buffer1, 0x1000+size);
  70.             fp = fopen(argv[2], "wvqb");
  71.             fwrite(buffer1, size, fp);
  72.             fclose(fp);
  73.             message("CMOS data saved");
  74.             break;
  75.         case 'r' :        /* Restore CMOS data from a file */
  76.         case 'R' :
  77.             fp = fopen(argv[2], "rvqb");
  78.             size = fread(buffer1, MAX_SIZE, fp);
  79.             fclose(fp);
  80.             write_cmos(buffer1, 0x1000+size);
  81.             message("CMOS data restored");
  82.             break;
  83.         case 'v' :        /* Verify CMOS data with file */
  84.         case 'V' :
  85.             fp = fopen(argv[2], "rvqb");
  86.             size = fread(buffer2, MAX_SIZE, fp);
  87.             fclose(fp);
  88.             read_cmos(buffer1, 0x1000+size);
  89.             for(i=0; i < icount; ++i)
  90.                 buffer1[ignore[i]] = buffer2[ignore[i]] = 0;
  91.             for(i=0; i < size; ++i) {
  92.                 if(buffer1[i] != buffer2[i]) {
  93.                     message("CMOS verify FAILED!!!");
  94.                     exit(-1); } }
  95.             message("CMOS Data verified");
  96.             break;
  97.         default:            /* Invalid command */
  98.             fputs("Unknown command: ", stderr);
  99.             fputs(argv[1], stderr);
  100.             return; }
  101. }
  102.  
  103. /*
  104.  * Issue message to used only if "verbose" enabled
  105.  */
  106. message(string)
  107.     char *string;
  108. {
  109.     if(verbose)
  110.         fputs(string, stdout);
  111. }
  112.  
  113. /*
  114.  * Read data from the CMOS ram
  115.  */
  116. read_cmos(dest, addr_size) asm
  117. {
  118.         MOV        BX,6[BP]        ; Get destination
  119.         MOV        CX,4[BP]        ; Get start/size
  120.         CLI                        ; Disallow interruptions
  121. rdloop:    MOV        AL,CH            ; Get address
  122.         OUT        70h,AL            ; Write it
  123.         INC        CH                ; Advance address
  124.         IN        AL,71h            ; Read the data
  125.         MOV        [BX],AL            ; Write it in dest
  126.         INC        BX                ; Advance destination
  127.         DEC        CL                ; Reduce count
  128.         JNZ        rdloop            ; And continue
  129.         STI                        ; Allow interruptions
  130. }
  131.  
  132. /*
  133.  * Write data to the CMOS ram
  134.  */
  135. write_cmos(source, addr_size) asm
  136. {
  137.         MOV        BX,6[BP]        ; Get destination
  138.         MOV        CX,4[BP]        ; Get start/size
  139.         CLI                        ; Disallow interruptions
  140. wrloop:    MOV        AL,CH            ; Get address
  141.         OUT        70h,AL            ; Write it
  142.         MOV        AL,[BX]            ; Get value to write
  143.         OUT        71h,AL            ; Write it
  144.         INC        CH                ; Advance address
  145.         INC        BX                ; Advance destination
  146.         DEC        CL                ; Reduce count
  147.         JNZ        wrloop            ; And continue
  148.         STI                        ; Allow interruptions
  149. }
  150.